package Netty.old.NIONetty.聊天;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * 说明
 * 1. 我们自定义一 -个Handler 需要继续netty规定好的某HandlerAdapter(规范)
 * 2.这时我们自定义一Handler，才能称为一个handler
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服务器读取线程" + Thread.currentThread().getName());
        System.out.println( "ctx:" + ctx);

        //channel和pipeline  互相包含   你中有我   我中有你
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = ctx.pipeline();//本质是个双线链表

        //将msg转成一个ByteBuf(Netty的缓存不是NIO的)
        ByteBuf buf = (ByteBuf) msg;
        System.out.println("客户端发送的信息:" + buf.toString(StandardCharsets.UTF_8));
        System.out.println("地址是:" + channel.remoteAddress());

        /*
        比如这里我们有一-个非常耗时长的业务->异步执行->提交该channel对应的
        NIOEventLoop的taskQueue中,
        解决方案1用户程序自定义的普通任务
         //ExecutorService threadPool= Executors.newSingleThreadExecutor();
         //线程池  一个  线程   类似一个窗口
         */
        ctx.channel().eventLoop().execute(()->{
            try {Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(6);
        });//放在ctx内置的线程池里，里面的线程池只有一个线程
        ctx.channel().eventLoop().schedule(()->{System.out.println(1);},5, TimeUnit.SECONDS);

        //这个放在ctx内置的线程池里，里面的线程池有多个线程
        ctx.channel().eventLoop().schedule(()->{System.out.println(2);},5, TimeUnit.SECONDS);

    }//读取数据实际(这里我们可以读取客户端发送的消息)

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //将write+flush  将数据写入到缓存，并刷新
        //一般将，我们对这个发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("我已经收到了",StandardCharsets.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }//处理异常
}
